package com.dxy.common.vo;

import com.dxy.common.exp.ServiceException;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;

@Setter
@Getter
public class Result<T> implements Serializable {

    private static final long serialVersionUID = -7464029455394317401L;

    public static final int OK_CODE = 200;
    public static final String OK_MSG = "success...";
    public static final int FAIL_CODE = -200;
    public static final String FAIL_MSG = "error...";

    private int code;
    private String msg;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private T data;
    private long timestamp;

    // json反序列化时必须要有默认的无参构造器
    public Result() {
        this.timestamp = System.currentTimeMillis();
    }

    private Result(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
        this.timestamp = System.currentTimeMillis();
    }

    @JsonIgnore
    public boolean isSuccess() {
        return OK_CODE == this.code;
    }

    @JsonIgnore
    public boolean isFail() {
        return !this.isSuccess();
    }

    private static <T> Result<T> getResult(int code, String msg, T data) {
        return new Result<>(code, msg, data);
    }

    public static <T> Result<T> ok() {
        return getResult(OK_CODE, OK_MSG, null);
    }

    public static <T> Result<T> ok(T data) {
        return getResult(OK_CODE, OK_MSG, data);
    }

    public static <T> Result<T> fail() {
        return getResult(FAIL_CODE, FAIL_MSG, null);
    }

    public static <T> Result<T> fail(String msg) {
        return getResult(FAIL_CODE, msg, null);
    }

    public static <T> Result<T> fail(T data) {
        return getResult(FAIL_CODE, FAIL_MSG, data);
    }

    public static <T> Result<T> fail(int code, String msg) {
        return getResult(code, msg, null);
    }

    public static <T> Result<T> fail(int code, String msg, T data) {
        return getResult(code, msg, data);
    }

    public static <T> Result<T> fail(ServiceException exception) {
        return getResult(exception.getCode(), exception.getMessage(), null);
    }

    public static <T> Result<T> fail(ServiceException exception, T data) {
        return getResult(exception.getCode(), exception.getMessage(), data);
    }

}
